package com.bianmaba.spring.data.jpa.repository.support;

import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.repository.NoRepositoryBean;

import javax.persistence.EntityManager;
import java.io.Serializable;
import java.util.List;
import java.util.Map;

/**
 * Created by cwx183898 on 2017/8/15.
 */
@NoRepositoryBean
public interface ExtendedRepository<T, ID extends Serializable> extends JpaRepository<T, ID>, JpaSpecificationExecutor<T> {
    EntityManager getEntityManager();

    /**
     * 根据一个属性和值查询数据，如果条件中路径中包含集合的属性时，将会自动去除重复数据
     *
     * @param property 属性
     * @param val      值
     * @return 去重复后的数据集合
     */
    List<T> findAllDistinctToList(String property, Object val);

    /**
     * 根据一个属性和值查询数据，支持分页，如果条件中路径中包含集合的属性时，将会自动去除重复数据
     *
     * @param property 属性
     * @param val      值
     * @param pageable 分页参数
     * @return 去重复后的数据集合
     */
    List<T> findAllDistinctToList(String property, Object val, Pageable pageable);

    /**
     * 根据一个属性和值查询数据，如果条件中路径中包含集合的属性时，将会自动去除重复数据
     *
     * @param property 属性
     * @param val      值
     * @return 数据去重复后的Page实体
     */
    Page<T> findAllDistinct(String property, Object val);

    /**
     * 根据一个属性和值查询数据，支持分页，如果条件中路径中包含集合的属性时，将会自动去除重复数据
     *
     * @param property 属性
     * @param val      值
     * @param pageable 分页参数
     * @return 数据去重复后的Page实体
     */
    Page<T> findAllDistinct(String property, Object val, Pageable pageable);

    /**
     * 根据一组参数列表查询数据，支持分页，如果条件中路径中包含集合的属性时，将会自动去除重复数据
     *
     * @param params   参数列表
     * @param pageable 分页参数
     * @return 数据去重复后的Page实体
     */
    Page<T> findAllDistinct(Map<String, Object> params, Pageable pageable);

    /**
     * 根据一组参数列表查询数据，支持分页，如果条件中路径中包含集合的属性时，将会自动去除重复数据
     *
     * @param params   参数列表
     * @param pageable 分页参数
     * @return 去重复后的数据集合
     */
    List<T> findAllDistinctToList(Map<String, Object> params, Pageable pageable);

    /**
     * 根据一个属性和值查询数据，支持分页，如果条件中路径中包含集合的属性时
     *
     * @param property 属性
     * @param val      值
     * @return 去重复后的数据集合
     */
    List<T> findAllToList(String property, Object val);

    /**
     * 根据一个属性和值查询数据，支持分页，如果条件中路径中包含集合的属性时
     *
     * @param property 属性
     * @param val      值
     * @param pageable 分页参数
     * @return 数据集合
     */
    List<T> findAllToList(String property, Object val, Pageable pageable);

    /**
     * 根据一个属性和值查询数据，如果条件中路径中包含集合的属性时
     *
     * @param property 属性
     * @param val      值
     * @return 包含数据集合的Page实体
     */
    Page<T> findAll(String property, Object val);

    /**
     * 根据一个属性和值查询数据，支持分页，如果条件中路径中包含集合的属性时
     *
     * @param property 属性
     * @param val      值
     * @param pageable 分页参数
     * @return 包含数据集合的Page实体
     */
    Page<T> findAll(String property, Object val, Pageable pageable);

    /**
     * 根据一组参数列表查询数据，支持分页，如果条件中路径中包含集合的属性时
     *
     * @param params   参数列表
     * @param pageable 分页参数
     * @return 包含数据集合的Page实体
     */
    Page<T> findAll(final Map<String, Object> params, final Pageable pageable);

    /**
     * 根据一组参数列表查询数据，支持分页，如果条件中路径中包含集合的属性时
     *
     * @param params   参数列表
     * @param pageable 分页参数
     * @return 数据集合
     */
    List<T> findAllToList(Map<String, Object> params, Pageable pageable);

    List executeSqlQuery(String sql);

    List executeSqlQuery(String sql, Object[] params);

    <E> List<E> executeSqlQuery(String sql, Class<E> entityClass);

    <E> List<E> executeSqlQuery(String sql, Object[] params, Class<E> entityClass);

    <E> List<E> executeSqlQuery(String sql, Object[] params, Integer firstResult, Integer maxResults, Class<E> entityClass);

    <E> E executeSqlQueryUniqueResult(String sql, Object[] params, Class<E> entityClass);

    Object executeSqlQuerySingleResult(String sql, Object[] params);

    Integer executeSqlUpdate(String sql);

    Integer executeSqlUpdate(String sql, Object[] params);

    void clear();

    void close();

    void detach(Object obj);

    void refresh(Object obj);
}
